using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using 后端服务.Models;

namespace 后端服务.Services
{
    /// <summary>
    /// 认证服务类，处理用户注册和身份验证
    /// </summary>
    public class AuthService
    {
        private readonly SqlQueryService _sqlQueryService;
        private readonly IPasswordHasher<User> _passwordHasher;
        private readonly ILogger<AuthService> _logger;
        private readonly JwtService _jwtService;
    
        /// <summary>
        /// 构造函数，注入所需依赖
        /// </summary>
        /// <param name="sqlQueryService">SQL查询服务</param>
        /// <param name="passwordHasher">密码哈希工具</param>
        /// <param name="jwtService">JWT服务</param>
        /// <param name="logger">日志服务</param>
        public AuthService(SqlQueryService sqlQueryService, IPasswordHasher<User> passwordHasher, JwtService jwtService, ILogger<AuthService> logger)
        {
            _sqlQueryService = sqlQueryService;
            _passwordHasher = passwordHasher;
            _jwtService = jwtService;
            _logger = logger;
        }

        /// <summary>
        /// 注册新用户
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="deviceInfo">设备信息（可选）</param>
        /// <returns>包含用户信息、JWT令牌和刷新令牌的元组</returns>
        public async Task<(User user, string token, string refreshToken)> Register(string username, string password, string deviceInfo = "")
        {
            // 检查用户名是否已存在
            var sql = "SELECT * FROM Users WHERE Username = :username";
            var parameters = new Dictionary<string, object>
            {
                { ":username", username }
            };
            var existingUser = (await _sqlQueryService.QueryAsync<User>(sql, parameters)).FirstOrDefault();
            if (existingUser != null)
            {
                throw new InvalidOperationException("用户名已存在");
            }

            // 创建新用户
            var user = new User
            {
                Username = username,
                IsAdmin = username.ToLower() == "admin", // 如果用户名为"admin"，则设置为管理员
                CreatedDate = DateTime.UtcNow
            };
        
            // 哈希密码
            user.PasswordHash = _passwordHasher.HashPassword(user, password);
        
            // 从序列获取新的 UserId
            sql = "SELECT USERS_SEQ.NEXTVAL FROM DUAL";
            var newUserId = await _sqlQueryService.ExecuteScalarAsync<int>(sql);

            // 将用户添加到数据库
            sql = @"INSERT INTO Users (UserId, Username, PasswordHash, IsAdmin, CreatedDate) 
                   VALUES (:userId, :username, :passwordHash, :isAdmin, :createdDate)";
            parameters = new Dictionary<string, object>
            {
                { ":userId", newUserId },
                { ":username", user.Username },
                { ":passwordHash", user.PasswordHash },
                { ":isAdmin", user.IsAdmin ? 1 : 0 },  // 将 bool 转换为 int
                { ":createdDate", user.CreatedDate }
            };
            
            await _sqlQueryService.ExecuteAsync(sql, parameters);
            user.UserId = newUserId;

            // 生成JWT令牌和刷新令牌
            var token = _jwtService.GenerateToken(user);
            var refreshToken = await _jwtService.GenerateRefreshToken(user, deviceInfo);

            return (user, token, refreshToken);
        }

        /// <summary>
        /// 验证用户身份
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="deviceInfo">设备信息（可选）</param>
        /// <returns>如果验证成功，返回包含用户信息、JWT令牌和刷新令牌的元组；否则返回null</returns>
        public async Task<(User user, string token, string refreshToken)?> Authenticate(string username, string password, string deviceInfo = "")
        {
            // 查找用户
            var sql = "SELECT * FROM Users WHERE Username = :username";
            var parameters = new Dictionary<string, object>
            {
                { ":username", username }
            };
            var user = (await _sqlQueryService.QueryAsync<User>(sql, parameters)).FirstOrDefault();
            
            if (user == null) return null;
        
            // 管理员特殊处理（不验证密码）
            if (user.IsAdmin) 
            {
                var token = _jwtService.GenerateToken(user);
                var refreshToken = await _jwtService.GenerateRefreshToken(user, deviceInfo);
                return (user, token, refreshToken);
            }
        
            // 验证密码
            var result = _passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
            if (result == PasswordVerificationResult.Success)
            {
                var token = _jwtService.GenerateToken(user);
                var refreshToken = await _jwtService.GenerateRefreshToken(user, deviceInfo);
                return (user, token, refreshToken);
            }

            return null; // 验证失败
        }

        /// <summary>
        /// 刷新访问令牌
        /// </summary>
        /// <param name="refreshToken">刷新令牌</param>
        /// <param name="deviceInfo">设备信息（可选）</param>
        /// <returns>如果刷新成功，返回包含用户信息、新的JWT令牌和新的刷新令牌的元组；否则返回null</returns>
        public async Task<(User user, string token, string newRefreshToken)?> RefreshToken(string refreshToken, string deviceInfo = "")
        {
            return await _jwtService.RefreshAccessToken(refreshToken, deviceInfo);
        }
    }
}